/*
 * Copyright 2000-2011 Worth Enterprises, Inc.  All Rights Reserved.
 */
package com.worthent.foundation.util.state;

import java.util.EventObject;

/**
 * Defines the basic event applied to the state transition table. The source is
 * always the {@link StateTableController} object that is processing the event.
 * Implementations of <code>StateTableControl</code> must invoke the
 * {@link #setSource} method within the implementation of the
 * {@link StateTableController#signalEvent(StateEvent)} method. The
 * {@link StateEngine} sets the working copy of the history.
 * 
 * @author Erik K. Worth
 * @version $Id: StateEvent.java 2 2011-11-28 00:10:06Z erik.k.worth@gmail.com $
 */
public class StateEvent extends EventObject {

    /**
     * The event source must not be <code>null</code> in the parent class.
     * Initialize it with this dummy implementation of the state table control
     * interface.
     */
    private static final Object UNINITIALIZED_SOURCE = new StateTableControl() {

        /** Do nothing */
        public void signalEvent(final StateEvent event)
            throws StateExeException {
            throw new StateExeException("Invalid state table control");
        }

        /** Do nothing */
        public void start() throws StateExeException {
            throw new StateExeException("Invalid state table control");
        }

        /** Do nothing */
        public void stop() throws StateExeException {
            throw new StateExeException("Invalid state table control");
        }

    };

    /** Serial ID */
    private static final long serialVersionUID = 4329781703732255140L;

    /** String identifier for this event */
    private final String name;

    /** The working copy of the state data object */
    private StateTableData dataObject;

    /** Creates a new instance of StateEvent */
    public StateEvent(final String name) {
        super(UNINITIALIZED_SOURCE);
        if (null == name) {
            throw new IllegalArgumentException("name must not be null");
        }
        this.name = name;
    }

    /** Called by the state table engine to set the working history */
    public final void setStateTableData(final StateTableData dataObject) {
        this.dataObject = dataObject;
    }

    /**
     * Called by the implementation of {@link StateTableController} that processes
     * the event.
     */
    public final void setStateTableControl(
        final StateTableControl stateTableControl) {
        source = stateTableControl;
    }

    /**
     * Returns the string identifier for this event.
     */
    public final String getName() {
        return name;
    }

    /**
     * Returns the state working copy of the state table data object. This may be
     * updated by actors during event processing. It should not be called before
     * submitting the event to the {@link StateEngine}.
     */
    public StateTableData getStateTableData() {
        return dataObject;
    }

    /**
     * Returns the state table control object processing the event.
     */
    public StateTableControl getStateTableControl() {
        return (StateTableControl) getSource();
    }

    /**
     * Returns the string identifier for this event.
     */
    @Override
    public String toString() {
        return name;
    }
} // StateEvent
